package src

import (
	//"runtime"
	"sync"
)
import "fmt"

//多个协程顺序打印 数字
func main() {
	//等待协程结束
	wg := new(sync.WaitGroup)
	/*	runtime.GOMAXPROCS(1)
		runtime.Gosched()*/
	//线程数
	limit := 200
	//start线程
	c := make(chan int)
	//重点  这个是循环线程的意思   将一个线程赋值这个next  下边的for循环会赋值给下一个协程
	next := c

	for i := 0; i < limit; i++ {
		//create协程的同时创建一个 管道 并赋值给下一个协程  保证输出的顺序性
		next = createGo(next, i+1, wg)
		fmt.Printf("next %s\n", next)
	}
	fmt.Printf("next %s\n", next)

	//启动协程
	c <- 0
	//next 为最后一个协程返回的管道 需要将这个管道的内容去除给c 管道 形成环
	for v := range next {
		c <- v
	}
	close(c)
	wg.Wait()
}

//创建协程 重点是返回一个管道 传递给下一个协程
func createGo(c chan int, no int, wg *sync.WaitGroup) chan int {
	wg.Add(1)                //添加一个等待
	notify := make(chan int) //创建一个协程

	//创建协程 带上管道参数
	go func(c chan int) {
		//协程结束后关闭协程
		defer func() {
			wg.Done()
		}()

		//读取管道里面的数据 管道没有数据阻塞住
		for d := range c {
			//结束条件
			if d > 100 {
				break
			}
			fmt.Printf("g%d print %d\n", no, d)
			//向下一个管道写入数据  激活下一个协程
			notify <- d + 1
		}
		//协程打印结束 关闭管道
		close(notify)
		fmt.Printf("g%d close g\n", no)
	}(c)
	return notify
}
